xtask\tasks\fmt\house_rules/
repr_packed.rs1use anyhow::anyhow;
5use fs_err::File;
6use std::io::BufRead;
7use std::io::BufReader;
8use std::io::Write;
9use std::path::Path;
10
11pub fn check_repr_packed(path: &Path, fix: bool) -> anyhow::Result<()> {
12 let ext = path
13 .extension()
14 .and_then(|e| e.to_str())
15 .unwrap_or_default();
16
17 if !matches!(ext, "rs") {
18 return Ok(());
19 }
20
21 let mut needs_fixing = false;
22 let f = BufReader::new(File::open(path)?);
23 for (i, line) in f.lines().enumerate() {
24 let line = line?;
25 if line.trim() == "#[repr(packed)]" {
26 needs_fixing = true;
27
28 let msg = format!("#[repr(packed)]: {}:{}", path.display(), i + 1);
29 if fix {
30 log::info!("fixing {}", msg);
31 } else {
32 log::error!("found {}", msg);
33 }
34 }
35 }
36
37 if fix && needs_fixing {
38 let path_fix = &{
39 let mut p = path.to_path_buf();
40 let ok = p.set_extension(format!("{}.fix", ext));
41 assert!(ok);
42 p
43 };
44
45 let f = BufReader::new(File::open(path)?);
46 let mut f_fixed = File::create(path_fix)?;
47
48 for line in f.lines() {
49 let line = line?;
50 if line.trim() == "#[repr(packed)]" {
51 let whitespace = line.split('#').next().unwrap();
52 writeln!(f_fixed, "{whitespace}#[repr(C, packed)]")?;
53 } else {
54 writeln!(f_fixed, "{}", line)?;
55 }
56 }
57
58 fs_err::rename(path_fix, path)?;
60 }
61
62 if needs_fixing && !fix {
63 Err(anyhow!(
64 "found uses of #[repr(packed)] in {}",
65 path.display()
66 ))
67 } else {
68 Ok(())
69 }
70}